#coding: utf-8 

from simData import *
from dijkstras import *
from position import *
from doors import *
from room import *


class Paths():
	"""
	Caminho de alto nível.
	1) Procurar quartos
	2) Sempre que se encontrar uma porta adiciona-la
	3) só se adiciona um quarto quando se conhecem todas as suas portas
	"""
	def __init__(self):
		self.graph={}
	
	def addNode(self,node):
		if node not in self.graph.keys():
			self.graph[node]={}
	
	def connect(self,node0,node1,value):
		if node0 in self.graph.keys() and node1 in self.graph.keys():
			self.graph[node0][node1]=value
			self.graph[node1][node0]=value
		else:
			raise KeyError,'Node not in keys'
	
	def addDoor(self,door):
		self.addNode(door)#self.graph[door]={}
	
	def findConnectiongRoom(self,door1,door2):
		from room import *
		nodes1=self.graph[door1]
		nodes2=self.graph[door2]
		
		rooms1=[]
		rooms2=[]
		
		for node in nodes1:
			if isinstance(node,Room):
				rooms1.append(node)
		for node in nodes2:
			if isinstance(node,Room):
				rooms2.append(node)
		
		for room1 in rooms1:
			for room2 in rooms2:
				if room1==room2:
					return room1
		
		return None
	
	def addRoom(self,room,doors):
		self.graph[room]={}
		
		for door in doors:
			if door not in self.graph.keys():
				print 'O elemento',door, 'não pertence ao graph'
				
		#adding rooms
		for door in doors:
			pos0=room.pos
			pos1=door.pos
			self.graph[door][room]=pos0.dist_to(pos1)
			self.graph[room][door]=pos0.dist_to(pos1)
		
		#adding door passages throught
		for door0 in doors:
			for door1 in doors:
				pos0=door0.pos
				pos1=door1.pos
				try:
					self.graph[door0][door1]
				except:
					self.graph[door0][door1]=None
				if self.graph[door0][door1] is None:
					self.graph[door0][door1]=pos0.dist_to(pos1)
				else:
					self.graph[door0][door1]=min(self.graph[door0][door1],pos0.dist_to(pos1))
				
	def shortestPath(self,de,to):
		if de in self.graph.keys() and to in self.graph.keys():
			return shortestPath(self.graph,de,to)
		else:
			raise KeyError,'Node not found'
	
	def shortestPathDist(self,de,to):
		if de in self.graph.keys() and to in self.graph.keys():
			return shortestPathDist(self.graph,de,to)
		else:
			raise KeyError,'Node not found'
			
	def saveGraph(self,filename):
		G=self.graph
		f = open(filename,'w')
		f.writelines('digraph G {\nnode [width=.3,height=.3,shape=octagon,style=filled,color=skyblue];\noverlap="false";\nrankdir="LR";\n')
		f.writelines
		for i in G:
			for j in G[i]:
				try:
					s= '      '+ '"' + str(i.name) + '"'
					s +=  ' -> ' + '"'+  str(j.name) + '"'+ ' [label="' + '%.2f' % G[i][j] + '"]'
				except:
					s= '      '+ '"' + str(i) + '"'
					s +=  ' -> ' + '"'+  str(j) + '"'+ ' [label="' + '%.2f' % G[i][j] + '"]'
				s+=';\n'
				f.writelines(s)

		f.writelines('}')
		f.close()
		
if __name__=='__main__':
	
	
	path=Paths()
	
	a='a'
	b='b'
	c='c'
	d='d'
	

	
	d0=Door(0,Position(1.0,2.0))
	path.addDoor(d0)
	d1=Door(1,Position(2.0,3.0))
	path.addDoor(d1)
	d2=Door(2,Position(3.0,2.0))
	path.addDoor(d2)
	d3=Door(3,Position(4.0,1.0))
	path.addDoor(d3)
	
	ra=Door(a,Position(1.0,3.0))
	path.addRoom(ra,[d0,d1])
	rb=Door(b,Position(3.0,3.0))
	path.addRoom(rb,[d1,d2])
	rc=Door(c,Position(2.0,1.0))
	path.addRoom(rc,[d0,d2,d3])
	rd=Door(d,Position(5.0,2.0))
	path.addRoom(rd,[d3])
	
	print path.graph
	
	d3 in path.graph.items()
	print shortestPath(path.graph,rc,rd)
	print shortestPath(path.graph,d1,rd)
